package medicos;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import pessoas.PessoaInexistenteException;
import pessoas.RepositorioPessoas;
import pessoas.RepositorioPessoasBDR;
import util.IllegalArgumentException;
import util.PersistenceMechanismException;
import util.PersistenceMechanismRDBMS;
import util.RepositorioException;
public class RepositorioMedicosBDR implements RepositorioMedicos {
	
		private static RepositorioMedicosBDR instance;
	    private PersistenceMechanismRDBMS pm;
		
	    private RepositorioMedicosBDR() {
	        try {
	            pm = PersistenceMechanismRDBMS.getInstance();
	            pm.connect();
	        }
	        catch (Exception ex) {
	            //System.out.println(ex.getMessage()); 
	            ex.printStackTrace();
	        }
	    }

	    public synchronized static RepositorioMedicosBDR getInstance() {
	        if (instance == null) {
	            instance = new RepositorioMedicosBDR();
	        }
	        return instance;
	    }


	    public void inserir(Medico medico) throws RepositorioException {
	    	try {
	            Statement statement = (Statement) pm.getCommunicationChannel();
	            statement.executeUpdate("INSERT INTO MEDICOS VALUES ('" +
	                                    medico.getMatricula() + "', '" +	                                    
	                                    medico.getCrm() + "', '" +
	                                    medico.getEspecializacao() + "')");
	            // atualizando agora a tabela pessoas
	            RepositorioPessoas rp = RepositorioPessoasBDR.getInstance();
	            rp.inserir(medico);
	            
	        } catch(PersistenceMechanismException e){
	            throw new RepositorioException(e);
	        } catch (SQLException e) {
	            throw new RepositorioException(e);
		    } finally {
			    try {
					pm.releaseCommunicationChannel();
				} catch (PersistenceMechanismException ex) {
					throw new RepositorioException(ex);
				}
	        }
	    }
	    
	    public void remover(long matricula) throws MedicoNaoEncontradoException, RepositorioException {
	        try{
	            Statement statement = (Statement) pm.getCommunicationChannel();
			    int i = statement.executeUpdate("DELETE FROM MEDICOS WHERE matricula='" + matricula + "'");
	            if (i == 0) {
	            	throw new MedicoNaoEncontradoException(matricula);
	            }
	            
	            // atualizando agora a tabela pessoas
	            RepositorioPessoas rp = RepositorioPessoasBDR.getInstance();
	            rp.remover(matricula);
	            
			} catch(PersistenceMechanismException e){
	            throw new RepositorioException(e);
			} catch(SQLException e){
	            throw new RepositorioException(e);            
			} catch (PessoaInexistenteException e) {
				throw new RepositorioException(e);
			} finally {
				try {
					pm.releaseCommunicationChannel();
				} catch (PersistenceMechanismException ex) {
					throw new RepositorioException(ex);
				}
			}
		}
	    
	    public Medico procurar(long matricula) throws MedicoNaoEncontradoException, RepositorioException {
	   	    Medico medico = null;
	        try {
	            Statement statement = (Statement) pm.getCommunicationChannel();
	            ResultSet resultset = statement.executeQuery("SELECT * FROM MEDICOS WHERE matricula = '" + matricula + "'");
	            if (resultset.next()) {	                
	            	
	            	medico = new Medico(resultset.getLong("matricula"), 
	            					null, null, null, null, null, null, null, null, null,
	            					resultset.getString("crm"), resultset.getString("especializacao"));

		            // atualizando agora a tabela pessoas
		            RepositorioPessoas rp = RepositorioPessoasBDR.getInstance();
		            rp.complementarPessoa(medico);
		            
	            } else {
	            	throw new MedicoNaoEncontradoException(matricula);
	            }
				resultset.close();
			} catch(PersistenceMechanismException e){
	            throw new RepositorioException(e);
	        } catch (SQLException e) {
				throw new RepositorioException(e);
			} catch (PessoaInexistenteException e) {
				throw new RepositorioException(e);
			} finally {
				try {
					pm.releaseCommunicationChannel();
				} catch (PersistenceMechanismException ex) {
					throw new RepositorioException(ex);
				}
			}
			return medico;
		}

		public void atualizar(Medico medico) throws MedicoNaoEncontradoException, RepositorioException, IllegalArgumentException {
		    try {
	    	    Statement statement = (Statement) pm.getCommunicationChannel();
	            int i = statement.executeUpdate("UPDATE MEDICOS SET crm = '" + medico.getCrm() +
	            								"', especializacao = '" + medico.getEspecializacao() +
	            								"' WHERE matricula = '" + medico.getCodigo() + "'");

	            // atualizando agora a tabela pessoas
	            RepositorioPessoas rp = RepositorioPessoasBDR.getInstance();
	            rp.atualizar(medico);
	            
	            if (i == 0) {
	            	throw new MedicoNaoEncontradoException(medico.getCodigo());
	            }
			} catch(PersistenceMechanismException e){
	            throw new RepositorioException(e);
			} catch (SQLException e) {
			    throw new RepositorioException(e);
		    } catch (PessoaInexistenteException e) {
		    	 throw new RepositorioException(e);
			} finally {
		    	try {
					pm.releaseCommunicationChannel();
				} catch (PersistenceMechanismException ex) {
					throw new RepositorioException(ex);
				}
			}
		}

		public boolean existe(long matricula) throws RepositorioException {
	        boolean resposta = false;
	        try {
	            Statement statement = (Statement) pm.getCommunicationChannel();
	            ResultSet resultset = statement.executeQuery("SELECT * FROM MEDICOS WHERE matricula = '" + matricula + "'");
	            resposta = resultset.next();
				resultset.close();
			} catch(PersistenceMechanismException e){
	            throw new RepositorioException(e);
	        } catch (SQLException e) {
				throw new RepositorioException(e);
			} finally {
				try {
					pm.releaseCommunicationChannel();
				} catch (PersistenceMechanismException ex) {
					throw new RepositorioException(ex);
				}
			}
	        return resposta;
	    }

	    public RepositorioMedicos getMedicos() throws RepositorioException {
	        RepositorioMedicos resposta = new RepositorioMedicosArray();
	        try {
	            Statement statement = (Statement) pm.getCommunicationChannel();
	            ResultSet resultset = statement.executeQuery("SELECT * FROM MEDICOS");
	            while (resultset.next()) {
	                Medico medico = new Medico(resultset.getLong("matricula"), 
        					null, null, null, null, null, null, null, null, null,
        					resultset.getString("crm"), resultset.getString("especializacao"));
	                // atualizando agora a tabela pessoas
		            RepositorioPessoas rp = RepositorioPessoasBDR.getInstance();
		            rp.complementarPessoa(medico);
		            
	                resposta.inserir(medico);
	            }
				resultset.close();
			} catch(PersistenceMechanismException e){
	            throw new RepositorioException(e);
	        } catch (SQLException e) {
				throw new RepositorioException(e);
			} catch (PessoaInexistenteException e) {
				throw new RepositorioException(e);
			} finally {
				try {
					pm.releaseCommunicationChannel();
				} catch (PersistenceMechanismException ex) {
					throw new RepositorioException(ex);
				}
			}
	        return resposta;
	    }

	    public IteratorMedicos getIterator() throws RepositorioException {
	        return this.getMedicos().getIterator();
	    }

	    
		public RepositorioMedicos procurar(Medico medico) throws RepositorioException {
			IteratorMedicos medicos = this.getIterator();
			RepositorioMedicos resposta = new RepositorioMedicosArray();
			while (medicos.hasNext()) {
				Medico m = medicos.next();
				if (m.match(medico)){
					resposta.inserir(m);
				} 
			}
			return resposta;
		}

	}

